<script setup lang="ts">
import { ref, watch } from 'vue'
import { ElIcon } from 'element-plus'
import { QuestionFilled } from '@element-plus/icons-vue'
import type { PropType, Ref } from 'vue'
import type { ConfigProp, ConfigValueOption } from './types'
import ConfigValue from './config-value.vue'
// props
const props = defineProps({
  formRef: {
    type: Function as PropType<(el: any) => void>
  },
  modelValue: {
    type: Object as PropType<Record<string, any>>,
    default: () => {}
  },
  valueClassBasic: {
    type: Boolean,
    default: true
  },
  customProps: {
    type: Array as PropType<ConfigProp[]>,
    default: undefined
  },
  valueOptions: {
    type: Array as PropType<ConfigValueOption[]>,
    default: undefined
  },
  useFor: {
    type: String as PropType<'add' | 'edit' | 'display'>,
    default: 'add'
  }
})

const emit = defineEmits<{
  (e: 'update:modelValue', model: any): void
}>()

const model: Ref<Record<string, any>> = ref(props.modelValue)

function isPropExisted(conditions: string[], model: Record<string, any>): boolean {
  return conditions.every((condition) => {
    const conditionPair = condition.split(':')
    if (conditionPair.length == 1) {
      return typeof model[conditionPair[0]] != 'undefined'
    } else if (conditionPair.length == 2) {
      return (
        typeof model[conditionPair[0]] != 'undefined' &&
        model[conditionPair[0]] + '' == conditionPair[1]
      )
    } else {
      throw '参数异常'
    }
  })
}

watch(model, (v, ov) => {
  emit('update:modelValue', v)
})
</script>

<template>
  <el-form :ref="formRef" :model="model">
    <el-form-item
      label="键名"
      prop="configKey"
      label-width="120px"
      :rules="{
        required: true,
        message: '请输入键名',
        trigger: 'blur'
      }"
    >
      <el-input
        v-model="model.configKey"
        :disabled="useFor == 'display' || useFor == 'edit'"
        placeholder="请输入键名"
      ></el-input>
    </el-form-item>

    <el-form-item
      v-if="valueClassBasic"
      label="键值"
      prop="value"
      label-width="120px"
      :rules="{
        required: true,
        message: '请输入键值',
        trigger: 'blur'
      }"
    >
      <config-value
        v-model="model.value"
        :type="model.valueClass"
        :options="valueOptions"
        :disabled="useFor == 'display'"
      />
    </el-form-item>
    <template v-else>
      <template v-for="(customProp, index) in customProps" :key="index">
        <el-form-item
          v-if="!customProp.conditions || isPropExisted(customProp.conditions, model.value)"
          :prop="'value.' + customProp.prop"
          label-width="120px"
          :rules="{
            required: true,
            message: '请输入' + customProp.label,
            trigger: 'blur'
          }"
        >
          <template #label>
            <el-tooltip
              v-if="customProp.description"
              placement="top"
              :content="customProp.description"
            >
            <span>
              <el-icon size="small">
                <QuestionFilled />
              </el-icon>
            </span>
            </el-tooltip>
            <span>
              {{ customProp.label }}
            </span>
          </template>
          <template #default>
            <config-value
              v-model="model.value[customProp.prop!]"
              :type="customProp.type"
              :options="customProp.options"
              :disabled="useFor == 'display'"
            />
          </template>
        </el-form-item>
      </template>
    </template>

    <el-form-item label="备注" prop="remark" label-width="120px">
      <el-input
        v-model="model.remark"
        type="textarea"
        :disabled="useFor == 'display'"
        placeholder="请输入备注信息"
      ></el-input>
    </el-form-item>
  </el-form>
</template>
